//
// brief: 		开关设备服务
// author:		yun
// date:		2017-02-07
// desc: 		处理开关类型服务所有的业务
// version:		v0.1
//

package worker

import (
	"errors"
	"encoding/json"
)

const (
	SEV_SWITCH_TYPE	= "switch"

	// 服务终端返回的三种消息类型 [操作结果|手动开关|查询结果]
	SEV_SWITCH_MSG_RESULT = "result"
	SEV_SWITCH_MSG_HAND = "hand"
	SEV_SWITCH_MSG_STATE = "state"

	// 服务的三种状态
	SEV_SWITCH_ST_OPEN = "open"
	SEV_SWITCH_ST_CLOSE = "close"
	SEV_SWITCH_ST_OFFLINE = "offline"

	// 设备两种操作
	SEV_SWITCH_OP = "operate"
	SEV_SWITCH_OP_OPEN = "open"
	SEV_SWITCH_OP_CLOSE = "close"
)

//
// 开关服务
//

type SevSwitch struct {
	Service
}

// 服务终端的消息格式
type switchMessage struct {
	Type 	string		`json:"type"`
	Data 	string		`json:"data"`
}

type switchPost struct {
	Type  	string		`json:"type"`
	Data 	 string		`json:"data"`
}


var (
	SEV_SWITCH_ERR = errors.New("Switch Err")
)


//
// 建立一个开关设备实例
// sevId: 服务ID号
// post: 接收服务产生推送消息通道
// notify: 接收服务产生通知消息通道
// sev: 建立成功地服务
//
func NewSwitch(sevId string, post chan []byte, notify chan []byte) (sev *SevSwitch) {

	if sevId == "" || post == nil|| notify == nil {
		return nil
	}

	sev = &SevSwitch{
		Service{
			Id: sevId,
			State: SEV_SWITCH_ST_OFFLINE,
			Operates: []string{},
			Post: post,
			Notify: notify,
		},
	}

	return
}

//
// 接收设备发送过来的消息
//
func (sev *SevSwitch)  Message(data interface{}) (err error) {
	err = SEV_SWITCH_ERR

	buf, ok := data.([]byte)
	if !ok {
		return
	}

	var msg switchMessage
	err = json.Unmarshal(buf, &msg)
	if err != nil {
		return
	}

	// 判断开关的状态是否发生改变
	if sev.State == msg.Data {
		return
	}

	// 更新服务的状态和服务的操作列表
	if msg.Data == SEV_SWITCH_ST_OPEN {
		sev.State = SEV_SWITCH_ST_OPEN
		sev.Operates = []string{SEV_SWITCH_OP_CLOSE}
	} else if msg.Data == SEV_SWITCH_ST_CLOSE {
		sev.State = SEV_SWITCH_ST_CLOSE
		sev.Operates = []string{SEV_SWITCH_OP_OPEN}
	} else if msg.Data == SEV_SWITCH_ST_OFFLINE {
		sev.State = SEV_SWITCH_ST_OFFLINE
		sev.Operates = []string{}
	} else {
		return
	}

	// 向外通知设备状态改变
	notify := Notify{
		SevId: sev.Id,
		Notify: SevNotify{
			Type: msg.Type,
			Date: sev.State,
		},
	}

	notify_buf, _ := json.Marshal(notify)
	sev.Notify <- notify_buf

	return nil
}


//
// 接收来自家庭的操作请求
//
func (sev *SevSwitch) Request(data interface{}) (err error) {
	err = SEV_SWITCH_ERR
	buf, ok := data.([]byte)
	if !ok {
		return
	}

	// 设备离线，不能操作设备
	if sev.State == SEV_SWITCH_ST_OFFLINE {
		// 告知操作者，设备离线
		notify := Notify{
			SevId: sev.Id,
			Notify: SevNotify{
				Type: SEV_SWITCH_MSG_STATE,
				Date: SEV_SWITCH_ST_OFFLINE,
			},
		}

		notify_buf, _ := json.Marshal(notify)
		sev.Notify <- notify_buf
	}

	// 解析消息请求
	var request SevRequest
	err = json.Unmarshal(buf, &request)
	if err != nil {
		return
	}


	if request.Type != SEV_SWITCH_OP {
		return
	}

	op, ok := request.Date.(string)
	if !ok {
		return
	}

	// 将操作转发给终端设备
	post := SevPost{
		SevId: sev.Id,
		Post: &switchPost{
			Type: request.Type,
			Data: op,
		},
	}

	post_buf, _ := json.Marshal(post)
	sev.Post <- post_buf

	return nil
}

//
// 获取设备信息
//
func (sev *SevSwitch) GetState() interface{} {
	info := SevStateInfo{
		State: sev.State,
		Operates: sev.Operates,
	}

	info_buf, _ := json.Marshal(info)
	return info_buf
}

